# from cmcc import parse_html
import asyncio
import json
import time
import aioredis
import motor
from phone import Phone

from baseHandler import init_logger
from util.cmcc_10086 import cmcc10086_qrcode
from util.cmcc_ft import get_weixin_h5


async def num_check(obj, conn):
    user_data = await conn.rpop("cmcc_user", encoding='utf-8')
    if user_data:
        username, passwd, use_time = user_data.split("|")
    else:
        return {"code": -1}
    print(obj)
    try:
        pay_channel = "WX"
        try:
            future = cmcc10086_qrcode(obj["tel_number"], obj['amount'], conn, pay_channel, username,
                                      passwd)
            result = await asyncio.wait_for(future, timeout=60)
        except asyncio.TimeoutError:
            result = {"code": '2', "message": "超时"}

        wx_url = result.get('qrcode')
        order_url = result.get('url')
        order_id = result.get('orderid')
        message = result.get("message")
        logger.info("%s|%s", obj['ordernumber'], message)
        if result['code'] == "511004":
            use_time = time.time() + 30 * 60
            user_data = "%s|%s|%s" % (username, passwd, use_time)
            await conn.lpush('cmcc_user', user_data)
        elif result['code'] == "511005":
            logger.info("下单超限")
        else:
            user_data = "%s|%s|%s" % (username, passwd, use_time)
            await conn.lpush('cmcc_user', user_data)

        if wx_url:
            return {"code": 0}
        else:
            return {"code": -1}
    except Exception as e:
        logger.info("%s取单失败", obj["tel_number"])
        logger.error(e, exc_info=True)
        result = {"code": 2, 'message': "取单失败"}

async def pre_order(obj, conn, supplier, amount):
    print(obj)
    p = Phone()
    prov_res = p.find(obj['tel_number'])
    if prov_res:
        logger.info(prov_res)
        unused = await conn.sismember("unused_85_prov", prov_res.get("province"))
        # if prov_res['province'] == '内蒙古':
        #     unused = yield self.application.redis.sismember("unused_85_prov", '内蒙')
        if unused:
            logger.info("%s交费不可用", prov_res.get("province"))
            return {"code": 2, "message": "%s关闭交易" % prov_res.get("province")}

    else:
        logger.info("%s归属地查询失败" % obj['telnumber'])
    if time.time() - obj["time"] > 30:
        # if time.time() - obj['time'] < 60:
        logger.info("%s大于30秒" % obj['ordernumber'])
        await db.rechange.update_one({"ordernumber": obj["ordernumber"]},
                                     {"$set": {
                                         "orderstate": "1"
                                     }})
        return
    await db.rechange.update_one({"ordernumber": obj["ordernumber"]},
                                 {"$set": {
                                     "orderstate": "8"
                                 }})

    try:
        try:
            # res = await num_check(obj,  conn)
            # if res["code"] != 0:
            #     logger.info("%s不可交费", obj['tel_number'])
            #     return {"code": -1}
            future = get_weixin_h5(obj["tel_number"], obj['amount'], conn)
            result = await asyncio.wait_for(future, timeout=60)
        except asyncio.TimeoutError:
            result = {"code": '2', "message": "超时"}
        logger.info(result)
        url = result.get('url')
        order_id = result.get('orderid')
        query_url = result.get("query_url")
        message = result.get("message")
        logger.info("%s|%s", obj['ordernumber'], message)

        if url:
            pre_queue_name = "PRE_CMCCFT_%s_%s" % (supplier, amount)
            obj.update(result)
            logger.info(pre_queue_name)

            await db.rechange.update_one({"ordernumber": obj["ordernumber"]},
                                                 {"$set": {'query_url': query_url,
                                                           'wx_url': url,
                                                           "orderstate": '8',
                                                           "orderid": order_id,
                                                           "pay_type": "wx_h5"
                                                           }
                                                  })
            await conn.lpush(pre_queue_name, json.dumps(obj))
            pre_queue_size = await conn.llen(pre_queue_name)
            logger.info(pre_queue_size)

        else:
            orderstate = '1'
            await db.rechange.update_one({"ordernumber": obj["ordernumber"]},
                                         {"$set": {"orderstate": orderstate, "message": message}})
    except Exception as e:
        logger.info("%s取单失败", obj["tel_number"])
        logger.error(e, exc_info=True)
        result = {"code": 2, 'message': "取单失败"}


async def periodic(supplier, amount):
    orderlist = await aioredis.create_redis(address=('localhost', 6379), loop=loop)
    order_poll = await aioredis.create_redis(address=('localhost', 6379), loop=loop)
    task_queue = []
    while True:
        try:
            pre_queue_name = "PRE_CMCCFT_%s_%s" % (supplier, amount)
            pre_queue_size = await orderlist.llen(pre_queue_name)
            pre_cmcc_queue_len_name = "pre_cmccft_queue_len_%s_%s" % (supplier, amount)
            pre_size = await orderlist.get(pre_cmcc_queue_len_name, encoding='utf-8')
            if pre_size:
                pre_size = int(pre_size)
            else:
                pre_size = 10
            logger.info("当前队列%s长度%s, 设置长度%s", pre_queue_name, pre_queue_size, pre_size)
            for i in task_queue:
                if i.done():
                    task_queue.remove(i)

            if len(task_queue) > 20:
                logger.info("任务过多")
                await  asyncio.sleep(1)
                continue

            if pre_queue_size < pre_size:
                queue_name = "%s_%s" % (supplier, amount)
                obj = await order_poll.brpop(queue_name, encoding='utf-8')
                logger.info(obj)
                obj = json.loads(obj[1].replace("'", '"'))
                my_task = asyncio.Task(pre_order(obj, orderlist, supplier, amount))
                task_queue.append(my_task)
                # await pre_order(obj, orderlist, supplier, amount)
            else:
                await asyncio.sleep(1)
        except Exception as e:
            logger.error(e)
            await asyncio.sleep(5)
            continue
    else:
        orderlist.close()
        await orderlist.wait_closed()


if __name__ == '__main__':
    loop = asyncio.get_event_loop()

    logger = init_logger('cmcc', '/app/log/cs_notify/pre_order_ft.log')

    supplier = 'M2018081416281534235296'
    asyncio.Task(periodic(supplier, '30'))
    asyncio.Task(periodic(supplier, '50'))
    asyncio.Task(periodic(supplier, '100'))
    asyncio.Task(periodic(supplier, '200'))
    client = motor.motor_tornado.MotorClient('mongodb://cs_user:cmcc5188@localhost:12018/cs_recharge')
    db = client.cs_recharge
    loop.run_forever()
